<script setup lang="ts">
import { ref } from 'vue'

interface Props {
  dataApi?: (option?: any) => Promise<any>
  selected?: any[]
  picked?: any[]
  multi?: boolean
  keyName?: string
}

const props = withDefaults(defineProps<Props>(), {
  dataApi: () => {
    return new Promise((resolve) => {
      resolve([])
    })
  },
  selected: () => {
    return []
  },
  picked: () => {
    return []
  },
  multi: true,
  keyName: 'userId'
})

const emit = defineEmits<{
  (e: 'change', checked: boolean, person: any): void
  (e: 'pick', person: any): void
}>()

const showData = ref<any[]>([])
const disabledData = ref<string[]>([])
const checkedData = ref<string[]>([])

const loading = ref(false)

const initData = () => {
  loading.value = true
  if (props.selected?.length) {
    disabledData.value = props.selected.map((item: any) => item[props.keyName])
  }
  if (props.picked?.length) {
    checkedData.value = props.picked.map((item: any) => item[props.keyName])
  }
  props
    .dataApi()
    .then((res: any) => {
      showData.value = res.map((item: any) => {
        return {
          ...item,
          value: props.multi ? disabledData.value.includes(item[props.keyName]) || checkedData.value.includes(item[props.keyName]) : false,
          disabled: disabledData.value.includes(item[props.keyName])
        }
      })
    })
    .finally(() => {
      loading.value = false
    })
}

initData()

const handleChange = (val: boolean, person: any) => {
  emit('change', val, person)
}

const handlePick = (val: any, person: any) => {
  showData.value.forEach((item: any) => {
    if (item[props.keyName] === person[props.keyName]) {
      item.value = true
    } else {
      item.value = false
    }
  })
  emit('pick', person)
}

const toggle = (val: boolean, person: any) => {
  const target = showData.value.find((item: any) => item[props.keyName] === person[props.keyName])
  if (target) {
    target.value = val
  }
}

const pick = (person: any) => {
  showData.value.forEach((item: any) => {
    if (item[props.keyName] === person[props.keyName]) {
      item.value = true
    } else {
      item.value = false
    }
  })
}

defineExpose({
  toggle,
  pick
})
</script>

<template>
  <div v-loading="loading" class="mode-all-wrapper">
    <div v-for="item in showData" :key="item[props.keyName]" class="person-line">
      <el-checkbox
        v-if="props.multi"
        v-model="item.value"
        :label="item.userName"
        :disabled="item.disabled"
        @change="
          (val: boolean) => {
            handleChange(val, item)
          }
        "
      >
        {{ item.userName }}
      </el-checkbox>
      <el-radio
        v-else
        v-model="item.value"
        :label="true"
        :disabled="item.disabled"
        @change="
          (val: any) => {
            handlePick(val, item)
          }
        "
      >
        {{ item.userName }}
      </el-radio>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.mode-all-wrapper {
  padding-left: 10px;
  min-height: 300px;
  .person-line {
    @include rect(100%, 40px);
    display: flex;
    align-items: center;
  }
}
</style>
